package pl.elka.pszt.controller.handler;

import java.util.HashMap;
import java.util.Map;

import pl.elka.pszt.controller.Controller;
import pl.elka.pszt.controller.event.AskEvent;
import pl.elka.pszt.controller.event.BaseEvent;
import pl.elka.pszt.controller.event.ExitEvent;
import pl.elka.pszt.controller.event.LoadKnowledgeEvent;
import pl.elka.pszt.controller.event.SetThreadsEvent;
import pl.elka.pszt.controller.event.view.ShowErrorEvent;
import pl.elka.pszt.controller.event.view.ShowInformationEvent;
import pl.elka.pszt.controller.event.view.ShowTextInFieldEvent;
import pl.elka.pszt.controller.event.view.ShowWarningEvent;

/**
 * Mapuje eventy na odpowiednie handlery.
 * 
 * @author Andrzej Makarewicz
 * 
 */
public class Handlers {
	
	private final Controller controller;
	private final Map<Class<? extends BaseEvent>, BaseHandler> handlers;
	
	public Handlers(Controller controller) {
		this.controller = controller;
		this.handlers = new HashMap<Class<? extends BaseEvent>, BaseHandler>();
		
		registerHandlers();
	}
	
	private void registerHandlers(){
		this.handlers.put(ExitEvent.class, new ExitHandler(controller));
		//
		this.handlers.put(AskEvent.class, new AskHandler(controller));
		this.handlers.put(LoadKnowledgeEvent.class, new LoadKnowledgeHandler(controller));
		this.handlers.put(SetThreadsEvent.class, new SetThreadsHandler(controller));
		//
		this.handlers.put(ShowInformationEvent.class, new ShowMessageHandler(controller));
		this.handlers.put(ShowWarningEvent.class, new ShowMessageHandler(controller));
		this.handlers.put(ShowErrorEvent.class, new ShowMessageHandler(controller));
		this.handlers.put(ShowTextInFieldEvent.class, new ShowTextInFieldHandler(controller));
	}
	
	/**
	 * Wywoluje odpowiadajacy eventowi handler.
	 * @param event
	 * @throws NotHandledException
	 */
	public void handleEvent(BaseEvent event) throws NotHandledException {
		BaseHandler handler = handlers.get(event.getClass());
		if (handler == null) throw new NotHandledException(event);
		
		handler.handleEvent(event);
	}
	
	public static class NotHandledException extends RuntimeException {
		private static final long serialVersionUID = 964289063901183419L;
		
		public NotHandledException(BaseEvent event) {
			super(event.getClass().getSimpleName() + " is not handled.");
		}
	}
	
}
